package cn.itrip.controller;

import cn.itrip.entity.ItripUser;
import cn.itrip.ex.TokenValidationFailedException;
import cn.itrip.service.ItripUserService;
import cn.itrip.service.SmsService;
import cn.itrip.service.TokenService;
import cn.itrip.utils.EmptyUtils;
import cn.itrip.utils.MD5;
import cn.itrip.vo.ItripTokenVO;
import cn.itrip.vo.R;
import cn.itrip.vo.auth.ItripUserVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.MailSendException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/api")
public class AuthController {

    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private ItripUserService itripUserService;
    @Resource
    private SmsService smsService;
    @Resource
    JavaMailSenderImpl mailSender;
    @Value("${spring.mail.username}")
    private String sender;
    @Resource
    private TokenService tokenService;

    @ApiOperation(value = "手机注册")
    @ApiResponses({ @ApiResponse(code = 200, message = "OK") })
    @PostMapping("/registerbyphone")
    public R registerbyphone(@RequestBody ItripUserVO userVO){
        if (itripUserService.exists(userVO.getUserCode())){
            return R.fail("用户已经存在");
        }
        ItripUser user = new ItripUser();
        user.setActivated(0);
//        验证码
        String code = RandomStringUtils.random(6, false, true);
        boolean b = smsService.sendSms(userVO.getUserCode(), new String[]{code, "5"});
        if (b){
            stringRedisTemplate.opsForValue().set(userVO.getUserCode(),code,5*60,TimeUnit.SECONDS);
            BeanUtils.copyProperties(userVO,user);
            boolean save = itripUserService.save(user);
            if (save){
                return R.success("用户注册成功，请激活！");
            }
        }
        return R.fail("用户注册失败！");
    }

    @ApiOperation(value = "帐号激活")
    @ApiResponses({ @ApiResponse(code = 200, message = "OK") })
    @PutMapping(value = {"/validatephone","/activate"})
    public R validatephone(String user,String code){
        String userCode = stringRedisTemplate.opsForValue().get(user);
        if (code.equals(userCode)){
            QueryWrapper<ItripUser> wrapper = new QueryWrapper<ItripUser>();
            wrapper.eq("userCode",user);
            ItripUser itripUser = itripUserService.getOne(wrapper);
            if (itripUser.getActivated()==0) {
                ItripUser u = new ItripUser();
                u.setId(itripUser.getId());
                u.setActivated(1);
                boolean save = itripUserService.updateById(u);
                if (save){
                    return R.success("验证成功");
                }
            }else {
                return R.fail("帐号已被激活，请勿重复激活！");
            }
        }
        return R.fail("验证失败");
    }

    @ApiOperation(value = "注册用户名重复性验证")
    @ApiResponses({ @ApiResponse(code = 200, message = "OK") })
    @GetMapping("/ckusr")
    public R ckusr(String name){
        QueryWrapper<ItripUser> wrapper = new QueryWrapper<ItripUser>();
        wrapper.eq("userCode",name);
        ItripUser itripUser = itripUserService.getOne(wrapper);
        if (itripUser==null){
            return R.success("用户名可用");
        }
        return R.fail("用户名不可用");
    }

    @ApiOperation(value = "邮箱注册")
    @ApiResponses({ @ApiResponse(code = 200, message = "OK") })
    @PostMapping("/doregister")
    public R doregister(@RequestBody ItripUserVO userVO){
        if (itripUserService.exists(userVO.getUserCode())){
            return R.fail("用户已经存在");
        }
        ItripUser user = new ItripUser();
        user.setActivated(0);
//        验证码
        String code = RandomStringUtils.random(6, false, true);
        String Email =userVO.getUserCode();
        SimpleMailMessage message = new SimpleMailMessage();
        message.setSubject("注册验证码");
        message.setText("注册验证码是：" + code);
        message.setTo(Email);
        message.setFrom(sender);
        try {
            mailSender.send(message);
        }catch (MailSendException e){
            return R.fail("邮箱不存在");
        }
        stringRedisTemplate.opsForValue().set(userVO.getUserCode(),code,5*60,TimeUnit.SECONDS);
        BeanUtils.copyProperties(userVO,user);
        boolean save = itripUserService.save(user);
        if (save){
            return R.success("邮件发送成功，请激活！");
        }
        return R.fail("用户注册失败！");
    }

    @ApiOperation(value = "登录")
    @ApiResponses({ @ApiResponse(code = 200, message = "OK") })
    @PostMapping(value = "/dologin",headers = {"user-agent"})
    public R doLogin(String name,String password,
                     HttpServletRequest request){
        try {
            ItripUser user = itripUserService.login(name,password);
            if (EmptyUtils.isNotEmpty(user)) {
                String userAgent = request.getHeader("user-agent");
                String token = tokenService.generateToken(userAgent, user);
                tokenService.save(token, user);
                ItripTokenVO vo = new ItripTokenVO(token, Calendar.getInstance().getTimeInMillis() + 2 * 60 * 60 * 1000, Calendar.getInstance().getTimeInMillis());
                return R.success("登录成功",vo);
            } else {
                return R.fail("用户名或密码错误");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(e.getMessage());
        }
    }

    @ApiOperation(value = "注销登录")
    @ApiResponses({ @ApiResponse(code = 200, message = "OK") })
    @GetMapping(value = "/logout",headers = {"token"})
    public R logout(HttpServletRequest request){
        String token = request.getHeader("token");
        try {
            String useragent = "user-agent";
            if (tokenService.validate(request.getHeader(useragent), token)) {
                tokenService.delete(token);
                return R.success("注销成功!");
            } else {
                return R.fail("token无效");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail("退出失败！");
        }
    }

    @ApiOperation(value = "Token置换")
    @ApiResponses({ @ApiResponse(code = 200, message = "OK") })
    @PostMapping(value = "/retoken",headers = {"user-agent","token"})
    public R retoken(HttpServletRequest request){
        String token = null;
        try {
            token = this.tokenService.replaceToken(request.getHeader("user-agent"), request.getHeader("token"));
            ItripTokenVO vo = new ItripTokenVO(token, Calendar.getInstance().getTimeInMillis() + 2 * 60 * 60 * 1000, Calendar.getInstance().getTimeInMillis());
            return R.success(null,vo);
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail(null);
        }
    }
}
